/**
 * @开发版权 
 * @项目名称 轻量数据中台(LDMP)
 * @版本信息 v1.0
 * @开发人员 zhous
 * @开发日期 2025-01-17
 * @修订日期
 * @描述  UserController
 */
package com.ng.sys.controller;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.ng.common.annotation.TokenRequired;
import com.ng.common.annotation.Tx;
import com.ng.common.constants.SecurityConstants;
import com.ng.common.controller.Controller;
import com.ng.common.enums.MenuTypeEnum;
import com.ng.common.model.request.UserPasswordRequest;
import com.ng.common.model.response.R;
import com.ng.common.util.DateUtil;
import com.ng.common.util.EncryptUtil;
import com.ng.common.util.RsaUtil;
import com.ng.common.util.UuidUtil;
import com.ng.sys.model.domain.*;
import com.ng.sys.model.request.ResetPwdRequest;
import com.ng.sys.model.response.UserProfileResponse;
import com.ng.sys.service.IUser;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;

@Tag(name = "用户管理")
@RequiredArgsConstructor
@RestController
@RequestMapping("/sys/user")
public class UserController extends Controller {

	@Autowired
	private IUser userImpl;

	@Operation(summary = "获取当前用户信息")
	@TokenRequired
	@GetMapping("/info")
	public R<User> info(HttpServletRequest request) {
		try {
			User user = User.dao.findById(this.getUserId(request));
			List<Role> roles = Role.dao.find("select code from " + Role.TABLE_NAME
					+ " where id in (select role_id from " + UserRole.TABLE_NAME + " where user_id=? ) ", user.getId());
			if (roles != null) {
				String userRoles[] = new String[roles.size()];
				int i = 0;
				for (Role r : roles) {
					userRoles[i] = r.getCode();
					i++;
				}
				user.setRoles(userRoles);
				List<Menu> menus = Menu.dao
						.find("select * from " + Menu.TABLE_NAME + " where type=? and id in ( select menu_id from "
								+ RoleMenu.TABLE_NAME + " where role_id in (select role_id from " + UserRole.TABLE_NAME
								+ " where user_id=? ) ) order by sort asc ",MenuTypeEnum.BUTTON.getType(), getUserId(request));
				if (menus != null) {
					List<String> userPerms = new LinkedList<String>();
					for (Menu menu : menus) {
						userPerms.add(menu.getPerm());
					}
					user.setPerms(userPerms);
				}
				user.setPassword("");
				return R.ok(user);
			}
			return R.failed("无效用户！");
		} catch (Exception e) {
			e.printStackTrace();
			return R.failed(401, "会话过期，请重新登录！");
		}
	}
	
	@Operation(summary = "获取当前用户外部系统信息")
	@TokenRequired
	@GetMapping("/outer/info")
	public R<User> getOuterinfo(HttpServletRequest request) {
		try {
			User user = User.dao.findById(this.getUserId(request));
			List<Role> roles = Role.dao.find("select code from " + Role.TABLE_NAME
					+ " where id in (select role_id from " + UserRole.TABLE_NAME + " where user_id=? ) ", user.getId());
			if (roles != null) {
				String userRoles[] = new String[roles.size()];
				int i = 0;
				for (Role r : roles) {
					userRoles[i] = r.getCode();
					i++;
				}
				user.setRoles(userRoles);
				List<Menu> menus = Menu.dao
						.find("select * from " + Menu.TABLE_NAME + " where type=? and use_type='1' and id in ( select menu_id from "
								+ RoleMenu.TABLE_NAME + " where role_id in (select role_id from " + UserRole.TABLE_NAME
								+ " where user_id=? ) ) order by sort asc ",MenuTypeEnum.BUTTON.getType(), getUserId(request));
				if (menus != null) {
					List<String> userPerms = new LinkedList<String>();
					for (Menu menu : menus) {
						userPerms.add(menu.getPerm());
					}
					user.setPerms(userPerms);
				}
				user.setPassword("");
				return R.ok(user);
			}
			return R.failed("无效用户！");
		} catch (Exception e) {
			e.printStackTrace();
			return R.failed(401, "会话过期，请重新登录！");
		}
	}
	
	@Operation(summary = "获取当前用户简介信息")
	@TokenRequired
	@GetMapping("/profile")
	public R<UserProfileResponse> profile(HttpServletRequest request) {
		User user = User.dao.findById(this.getUserId(request));
		if (user != null) {
			UserProfileResponse userProfileResponse=new UserProfileResponse();
			userProfileResponse.setId(user.getId());
			userProfileResponse.setUsername(user.getUsername());
			userProfileResponse.setName(user.getName());
			userProfileResponse.setAvatar(user.getAvatar());
			userProfileResponse.setGender(user.getGender());
			userProfileResponse.setMobile(user.getMobile());
			userProfileResponse.setEmail(user.getEmail());
			userProfileResponse.setCertificatenum(user.getCertificatenum());
			if(user.getCreateTime()!=null) {
				userProfileResponse.setCreateTime(DateUtil.getFormatDate(user.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
			}
			Dept dept=Dept.dao.findById(user.getDeptId());
			if(dept!=null) {
				userProfileResponse.setDeptName(dept.getName());
			}
			List<Role> roles=Role.dao.find("select * from "+Role.TABLE_NAME+" where id in (select role_id from sys_user_role where user_id=? ) ",user.getId());
			StringBuffer sb=new StringBuffer();
			for(Role role:roles) {
				sb.append(role.getName()).append(",");
			}
			userProfileResponse.setRoleNames(sb.length()>0?sb.substring(0, sb.length()-1):"");
			return R.ok(userProfileResponse);
		}
		return R.failed("无效用户！");
	}

	@Operation(summary = "分页获取用户列表")
	@Parameters({ @Parameter(name = "keywords", description = "关键字", required = false),
			@Parameter(name = "deptId", description = "部门Id", required = false),
			@Parameter(name = "status", description = "状态(1-正常 0禁用 -1-锁定)", required = false),
			@Parameter(name = "cur", description = "当前页码", required = true),
			@Parameter(name = "limit", description = "每页数据量", required = true) })
	@TokenRequired
	@GetMapping(value = { "/pages" }, produces = "application/json; charset=utf-8")
	public R<Page<User>> pages(HttpServletRequest request,
			@RequestParam(name = "keywords", required = false, defaultValue = "") String keywords,
			@RequestParam(name = "deptId", required = false, defaultValue = "") String deptId,
			@RequestParam(name = "status", required = false, defaultValue = "") String status,
			@RequestParam(name = "cur", required = false, defaultValue = "1") int cur,
			@RequestParam(name = "limit", required = false, defaultValue = "10") int limit) throws Exception {

		String sqlExceptSelect = " from " + User.TABLE_NAME + "  a WHERE 1=1 ";
		if (!StrKit.isBlank(keywords)) {
			sqlExceptSelect += " and (a.name like '%" + keywords + "%' or a.certificatenum like '%" + keywords
					+ "%' or a.mobile like '%" + keywords + "%' or a.username like '%" + keywords + "%' or a.name like '%" + keywords + "%' ) ";
		}
		if (!StrKit.isBlank(deptId)) {
			sqlExceptSelect += " and a.dept_id like '%" + deptId + "%' ";
		}
		if (!StrKit.isBlank(status)) {
			sqlExceptSelect += " and a.status = '" + status + "' ";
		}
		Page<User> page = User.dao.paginate(cur, limit,
				"select a.*,(select name from " + Dept.TABLE_NAME + " where id=a.dept_id) as deptName ",
				sqlExceptSelect);
		for (User user : page.getList()) {
			user.setUserRoles(
					UserRole.dao.find("select role_id from " + UserRole.TABLE_NAME + " where user_id=?", user.getId()));

		}
		return R.ok(page);
	}

	@Operation(summary = "保存用户")
	@Parameters({ @Parameter(name = "user", description = "用户", required = true) })
	@TokenRequired
	@Tx
	@PostMapping("/save")
	public R<User> save(HttpServletRequest request, @RequestBody User user) {
		try {
			if (StrKit.notBlank(user.getId())) {
				User checkUser=User.dao.findFirst("select * from "+User.TABLE_NAME+" where id!=? and username=? ",user.getId(),user.getUsername());
				if(checkUser!=null) {
					return R.failed("账号已存在！");
				}
				
				user.setUpdateTime(new Date(System.currentTimeMillis()));
				user.setUpdateUserId(getUserId(request));
				if (user.update()) {
					if (!StrKit.isBlank(user.getRoleIds())) {
						JSONArray arr = JSONObject.parseArray(user.getRoleIds());
						List<String> sqlList = new LinkedList<String>();
						StringBuffer sb = new StringBuffer();
						for (Object obj : arr) {
							String roleId = obj.toString();
							UserRole userRole = UserRole.dao.findByIds(user.getId(), roleId);
							if (userRole == null) {
								sqlList.add("insert " + UserRole.TABLE_NAME + " (user_id,role_id) VALUES('"
										+ user.getId() + "','" + roleId + "')");
							}
							sb.append("'").append(roleId).append("',");
						}
						if (!StrKit.isBlank(sb.toString())) {
							sqlList.add("delete from " + UserRole.TABLE_NAME + " where user_id='" + user.getId()
									+ "' and role_id not in(" + sb.toString().substring(0, sb.length() - 1) + ") ");
						}
						Db.batch(sqlList, sqlList.size());
					} else {
						Db.delete("delete from " + UserRole.TABLE_NAME + " where user_id=?", user.getId());
					}
					return R.ok(user);
				} else {
					return R.failed("更新失败！");
				}
			} else {
				
				User checkUser=User.dao.findFirst("select * from "+User.TABLE_NAME+" where username=? ",user.getUsername());
				if(checkUser!=null) {
					return R.failed("账号已存在！");
				}
				
				user.setId(UuidUtil.getUUID());
				user.setPassword(EncryptUtil.encrypt("rs@123"));
				user.setParentId(this.getUserId(request));
				user.setCreateTime(new Date(System.currentTimeMillis()));
				user.setCreateUserId(this.getUserId(request));
				if (user.save()) {
					if (!StrKit.isBlank(user.getRoleIds())) {
						JSONArray arr = JSONObject.parseArray(user.getRoleIds());
						List<String> sqlList = new LinkedList<String>();
						StringBuffer sb = new StringBuffer();
						for (Object obj : arr) {
							String roleId = obj.toString();
							UserRole userRole = UserRole.dao.findByIds(user.getId(), roleId);
							if (userRole == null) {
								sqlList.add("insert " + UserRole.TABLE_NAME + " (user_id,role_id) VALUES('"
										+ user.getId() + "','" + roleId + "')");
							}
							sb.append("'").append(roleId).append("',");
						}
						if (!StrKit.isBlank(sb.toString())) {
							sqlList.add("delete from " + UserRole.TABLE_NAME + " where user_id='" + user.getId()
									+ "' and role_id not in(" + sb.toString().substring(0, sb.length() - 1) + ") ");
						}
						Db.batch(sqlList, sqlList.size());
					} else {
						Db.delete("delete from " + UserRole.TABLE_NAME + " where user_id=?", user.getId());
					}
					return R.ok(user);
				} else {
					return R.failed("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

	@Operation(summary = "删除用户")
	@Parameters({ @Parameter(name = "id", description = "用户id集合(逗号分隔)", required = true) })
	@DeleteMapping("/{ids}")
	@TokenRequired
	public R<String> deleteMenu(@PathVariable("ids") String ids) {
		String[] arr=ids.split(",");
		if(ids==null || ids.length()<=0) {
			return R.failed("请选择需要删除的字典.");
		}
		for(String id:arr) {
			userImpl.delete(id);
		}
		return R.ok();
	}

	@Operation(summary = "重置用户密码")
	@Parameters({ @Parameter(name = "resetPwdRequest", description = "参数", required = true) })
	@Tx
	@TokenRequired
	@RequestMapping(value = "/resetPwd", method = RequestMethod.POST)
	public R<User> resetPwd(@RequestBody ResetPwdRequest resetPwdRequest) {
		User user=new User();
		user.setId(resetPwdRequest.getId());
		user.setPassword(EncryptUtil.encrypt(resetPwdRequest.getPassword()));
		if (user.update())
			return R.ok();
		return R.failed();
	}

	@Operation(summary = "修改用户密码")
	@Parameters({ @Parameter(name = "userpassword", description = "用户密码", required = true) })
	@TokenRequired
	@Tx
	@RequestMapping(value = "/password", method = RequestMethod.POST)
	public R<User> password(HttpServletRequest request, @RequestBody UserPasswordRequest userpassword) {
		try {
			if (userpassword == null || StrKit.isBlank(userpassword.getOldPassword())
					|| StrKit.isBlank(userpassword.getNewPassword())) {
				return R.failed("参数必填.");
			}
			String oldPwd = "";
			String newPwd = "";
			try {
				oldPwd = RsaUtil.decrypt(userpassword.getOldPassword(), SecurityConstants.PRIVATE_KEY);
				newPwd = RsaUtil.decrypt(userpassword.getNewPassword(), SecurityConstants.PRIVATE_KEY);
			} catch (Exception e) {
				e.printStackTrace();
				return R.failed("解密信息失败!");
			}

			User user = User.dao.findById(request.getAttribute("currentUserId"));
			if (user == null) {
				return R.failed("用户不存在.");
			}

			if (!EncryptUtil.matches(oldPwd, user.getPassword())) {
				return R.failed("原始密码错误.");
			}
			user.setPassword(EncryptUtil.encrypt(newPwd));
			if (user.update()) {
				return R.ok();
			} else {
				return R.failed("失败.");
			}
		} catch (Exception e) {
			return R.failed(e.getMessage());
		}
	}

	@Operation(summary = "用户授权角色")
	@Parameters({ @Parameter(name = "user", description = "用户(只需带Id)", required = true) })
	@TokenRequired
	@RequestMapping(value = "/roles", method = RequestMethod.POST)
	public R<List<UserRole>> getUserRoles(HttpServletRequest request, @RequestBody User user) {
		return R.ok(UserRole.dao.find("select role_id from sys_user_role where 1=1 and user_id=?", user.getId()));
	}

}
